﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
namespace NASM_Develop_IDE
{
    public partial class NasmEditTabList : UserControl
    {
        private Dictionary<ScintillaNET.Scintilla, string> _tabs;
        public Solution Solution { get; set; }
        public NasmEditTabList()
        {
          
            InitializeComponent();
            _tabs = new Dictionary<ScintillaNET.Scintilla, string>();
        }
        public Dictionary<ScintillaNET.Scintilla, string> Tabs
        {
            get
            {
                return _tabs;
            }
        }
        public void Foreach(Action<ScintillaNET.Scintilla> a)
        {
            _tabs.Keys.ToList().ForEach(delegate(ScintillaNET.Scintilla obj)
            {
                a(obj);
            });
        }
        public void RemoveTab(int index)
        {
            _tabs.Remove(tabs.TabPages[index].Controls[0] as ScintillaNET.Scintilla);
            tabs.TabPages.RemoveAt(index);
        }
        [Obsolete("Just Do Not Use It; Thought I Needed But The Other Overload Does A Better Job In My Opinion!", true)]
        public void AddTab(string nameOfSource, string author = "Mr. No Jobs")
        {
            ScintillaNET.Scintilla edit = new ScintillaNET.Scintilla();
            
            edit.Margins[0].Width = 15;
            edit.Margins[1].Width = 15;    
            edit.ConfigurationManager.CustomLocation = "nasm.xml";
            edit.ConfigurationManager.Language = "asm";
            edit.ConfigurationManager.Configure();
            TabPage page;
            if (!nameOfSource.EndsWith(".asm"))
            {
                page = new TabPage(nameOfSource + ".asm");
            }
            else
            {
                page = new TabPage(nameOfSource);
            }
            edit.Text = "; Author: " + author + "\n;Created On: " + DateTime.Now.ToString();
            edit.Dock = DockStyle.Fill;
            page.Controls.Add(edit);
            tabs.TabPages.Add(page);
            _tabs.Add(edit, nameOfSource + ".asm");
        }
        public void AddTab(string pathOfSource)
        {
            ScintillaNET.Scintilla edit = new ScintillaNET.Scintilla();
            
            edit.Margins[0].Width = 15;
            edit.Margins[1].Width = 32;
            edit.Margins[1].IsMarkerMargin = true;
            edit.Margins[1].Type = ScintillaNET.MarginType.Symbol;
            edit.Markers[1].Symbol = ScintillaNET.MarkerSymbol.Arrows;
            edit.Markers[1].ForeColor = Color.Red;
            edit.ConfigurationManager.CustomLocation = "nasm.xml";
            edit.ConfigurationManager.Language = "asm";

            edit.ConfigurationManager.Configure();

            using (FileStream stream = File.Open(pathOfSource, FileMode.Open))
            {
                using(StreamReader reader = new StreamReader(stream))
                {
                    string nameOfSource = Path.GetFileName(pathOfSource);
                    TabPage page;
                    if (!nameOfSource.EndsWith(".asm"))
                    {
                        page = new TabPage(nameOfSource + ".asm");
                    }
                    else
                    {
                        page = new TabPage(nameOfSource);
                    }
                    edit.Text = "; Author: Unknown" + "\n;Created On: " + DateTime.Now.ToString();
                    edit.Dock = DockStyle.Fill;
                    string source =  reader.ReadToEnd();
                    if (source != "")
                    {
                        edit.Text = (source);
                    }
                    page.Controls.Add(edit);
                    tabs.TabPages.Add(page);
                    if (!nameOfSource.EndsWith(".asm"))
                    {
                        _tabs.Add(edit, pathOfSource + ".asm");
                    }
                    else
                    {
                        _tabs.Add(edit, pathOfSource);
                    }
                }
            }
            
        }
        [Obsolete("This method is deprecated because its sole purpose is for debugging purposes. The programmer should not use it for non-debugging purposes!", false)]
        public void AddUntitledTab()
        {
           
            ScintillaNET.Scintilla edit = new ScintillaNET.Scintilla();
            edit.ConfigurationManager.CustomLocation = "nasm.xml";
            edit.ConfigurationManager.Language = "asm";
            edit.Margins[0].Width = 15;
            edit.Margins[1].Width = 15;         
            edit.ConfigurationManager.Configure();

            TabPage page = new TabPage("Untitled.asm");
            edit.Dock = DockStyle.Fill;
            page.Controls.Add(edit);
            tabs.TabPages.Add(page);
            _tabs.Add(edit, "Untitled.asm");

        }
        public void RenameTab(string oldName, string newName)
        {
           
            List<TabPage> pages = new List<TabPage>((IEnumerable<TabPage>)tabs.TabPages);
            pages.ForEach(delegate(TabPage page)
            {
                if (page.Text == oldName)
                {
                    
                    _tabs[page.Controls[0] as ScintillaNET.Scintilla] = newName;
                    page.Text = newName;
                }
            });
        }
        public void RenameTab(int index, string newName)
        {
            List<TabPage> pages = new List<TabPage>((IEnumerable<TabPage>)tabs.TabPages);
            _tabs[pages[index].Controls[0] as ScintillaNET.Scintilla] = newName;
            pages[index].Text = newName;
        }
        public void SetErrorAt(int tabIndex, int line)
        {
            ScintillaNET.Scintilla edit = tabs.TabPages[tabIndex].Controls[0] as ScintillaNET.Scintilla;
            edit.Lines[line - 1].AddMarker(1);
        }
        public void SetErrorAt(string sourceName, int line)
        {

            ScintillaNET.Scintilla edit = getScintilla(sourceName);
            edit.Lines[line - 1].AddMarker(1);
        }
        public void RemoveErrorAt(string sourceName, int line)
        {
            ScintillaNET.Scintilla edit = getScintilla(sourceName);
            edit.Lines[line - 1].DeleteMarker(1);
        }
        private void RemoveErrorAt(int tabIndex, int line)
        {
            ScintillaNET.Scintilla edit = tabs.TabPages[tabIndex].Controls[0] as ScintillaNET.Scintilla;
            edit.Lines[line - 1].DeleteMarker(1);
        }
        public void ClearAllError()
        {
            for (int index = 0; index < tabs.TabCount; index++)
            {
                ScintillaNET.Scintilla edit = tabs.TabPages[index].Controls[0] as ScintillaNET.Scintilla;
                for(int line = 0; line < edit.Lines.Count; line++)
                {
                    RemoveErrorAt(index, line);
                }
            }
        }
        private ScintillaNET.Scintilla getScintilla(string sourceName)
        {
            foreach (TabPage page in tabs.TabPages)
            {
                if (page.Text == sourceName)
                {
                    return page.Controls[0] as ScintillaNET.Scintilla;
                }
            }
            return null;
        }
        private void tabs_DoubleClick(object sender, EventArgs e)
        {
            
        }

        private void tabs_MouseUp(object sender, MouseEventArgs e)
        {
           
        }
        public KeyValuePair<ScintillaNET.Scintilla, string>? SelectedTab
        {
            get
            {
                if (tabs.SelectedTab != null)
                {
                    if (tabs.SelectedTab.Controls.Count > 0)
                        return new KeyValuePair<ScintillaNET.Scintilla, string>(tabs.SelectedTab.Controls[0] as ScintillaNET.Scintilla, tabs.SelectedTab.Text);
                    else
                        return null;

                }
                else
                {
                    
                    return null;
                }
            }
        }
        private void tabs_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                if (e.Control && e.KeyCode == Keys.N && Solution != null)
                {
                    using (NewTabDialog dlg = new NewTabDialog())
                    {
                        DialogResult result = dlg.ShowDialog();
                        if (result == System.Windows.Forms.DialogResult.OK)
                        {
                            using (FileStream stream = File.Create(Path.GetDirectoryName(Solution.AbsolutePathOfSources[0]) + "\\" + dlg.SourceName))
                            {
                                using (StreamWriter writer = new StreamWriter(stream))
                                {
                                    writer.WriteLine(";Source Name: " + dlg.SourceName + "\n; Created On: " + DateTime.Now.ToString());
                                }
                            }
                            AddTab(Path.GetDirectoryName(Solution.AbsolutePathOfSources[0]) + "\\" + dlg.SourceName);
                            Solution.AbsolutePathOfSources.Add(Path.GetDirectoryName(Solution.AbsolutePathOfSources[0]) + "\\" + dlg.SourceName);
                            
                            Solution.Save(this);
                        }
                    }
                }
            }
            catch
            {
               
            }
        }
    }
}
